﻿using System;
using System.Drawing;
using System.Windows.Forms;
using Game.Foundation;
using Game.Foundation.ChineseChess;
using System.Runtime.Remoting.Messaging;
using Bruce.Net;

namespace Game.Client.ChineseChess
{
    public partial class ChineseChessGameForm : Form, IChildClient
    {
        private GameStatus _status;
        private ChessboardClient _board;
        private Label _selected;
        private string _myName;
        //private string _currentUserName;
        private string _key;
        private int _mySeatIndex;
        private int _currentSeatIndex;
        private Camp _myCamp;

        public ChineseChessGameForm(string username, string key, int seatIndex)
        {
            InitializeComponent();

            this._myName = username;
            this._key = key;
            this._mySeatIndex = seatIndex;

            this._board = new ChessboardClient(this.panelChessBoard);
            this.DrawChessBoard();
        }

        private void DrawChessBoard()
        {
            Image bgChessBoard = new Bitmap(this.panelChessBoard.Width, this.panelChessBoard.Height);
            using (Graphics g = Graphics.FromImage(bgChessBoard))
            {
                Pen p = new Pen(Color.Black, 2);

                for (int i = 0; i < Chessboard.RowCount; i++)
                {
                    g.DrawLine(p, this._board.Points[i, 0], this._board.Points[i, Chessboard.ColumnCount - 1]);
                }
                for (int j = 0; j < 9; j++)
                {
                    g.DrawLine(p, this._board.Points[0, j], this._board.Points[Chessboard.RowCount - 1, j]);
                }
                g.DrawLine(p, this._board.Points[0, 3], this._board.Points[2, 5]);
                g.DrawLine(p, this._board.Points[0, 5], this._board.Points[2, 3]);
                g.DrawLine(p, this._board.Points[9, 3], this._board.Points[7, 5]);
                g.DrawLine(p, this._board.Points[9, 5], this._board.Points[7, 3]);
                g.FillRectangle(new SolidBrush(Color.Silver), new Rectangle(this._board.Points[4, 0], new Size(ChessboardClient.CellSize * 8, ChessboardClient.CellSize)));
            }

            this.panelChessBoard.BackgroundImage = bgChessBoard;
        }

        void lable_Click(object sender, EventArgs e)
        {
            if (this._currentSeatIndex != this._mySeatIndex) return;


            Label selected = sender as Label;
            ChessmanBase chessman = selected.Tag as ChessmanBase;

            if (this._selected == null)
            {
                if (chessman.Camp == this._myCamp)
                {
                    selected.BorderStyle = BorderStyle.FixedSingle;
                    this._selected = selected;
                }
            }
            else
            {
                if (chessman.Camp == this._myCamp)
                {
                    this._selected.BorderStyle = BorderStyle.None;
                    selected.BorderStyle = BorderStyle.FixedSingle;
                    this._selected = selected;
                }
                else
                {
                    ChessmanBase myChessman = this._selected.Tag as ChessmanBase;
                    int xOld = myChessman.XLocation, yOld = myChessman.YLocation;
                    if (myChessman.CanMoveTo(chessman.XLocation, chessman.YLocation))
                    {
                        this.DoOperation(xOld, yOld, chessman.XLocation, chessman.YLocation);
                    }
                }
            }
        }

        private void btnReady_Click(object sender, EventArgs e)
        {
            RemoteServer.GetSingletomServer(Program.RemotePort).RequestChangeStatus(this._key, GameStatus.Ready);
        }

        private void btnUnready_Click(object sender, EventArgs e)
        {
            RemoteServer.GetSingletomServer(Program.RemotePort).RequestChangeStatus(this._key, GameStatus.Unready);
        }

        private void panelChessBoard_MouseClick(object sender, MouseEventArgs e)
        {
            if (this._selected == null) return;

            ChessmanBase chessman = this._selected.Tag as ChessmanBase;
            int xLocation = 0, yLocation = 0;
            if (this._board.GetAssociateLocation(e.Location, out xLocation, out yLocation))
            {
                int xOld = chessman.XLocation, yOld = chessman.YLocation;
                //if (this._board.MoveChessman(chessman, xLocation, yLocation))
                if (chessman.CanMoveTo(xLocation, yLocation))
                {
                    this.DoOperation(xOld, yOld, xLocation, yLocation);
                }
            }
        }

        private void DoOperation(int xOld, int yOld, int xNew, int yNew)
        {
            this._selected.BorderStyle = BorderStyle.None;
            Packet p = new Packet((int)PacketType.游戏操作请求包);
            p.WriteInt32(xOld);
            p.WriteInt32(yOld);
            p.WriteInt32(xNew);
            p.WriteInt32(yNew);

            RemoteServer.GetSingletomServer(Program.RemotePort).RequestDoOperation(this._key, p.ToBinary());
        }

        #region IChildClient 成员

        public GameStatus Status
        {
            get
            {
                return this._status;
            }
            set
            {
                this._status = value;

                this.DoActionCrossThreads(() =>
                        {
                            switch (value)
                            {
                                case GameStatus.Gaming:
                                    btnReady.Visible = false;
                                    btnUnready.Visible = false;
                                    break;
                                case GameStatus.Ready:
                                    btnReady.Visible = false;
                                    btnUnready.Visible = true;
                                    break;
                                case GameStatus.Unready:
                                    btnUnready.Visible = false;
                                    btnReady.Visible = true;
                                    break;
                            }
                        });
            }
        }

        public void Initialize(byte[] buffer)
        {
            Packet initialPacket = (Packet)PacketLoader.Default.Parse(buffer);
            int deskId = initialPacket.ReadInt32();
            int playerCount = initialPacket.ReadInt32();
            for (int i = 0; i < playerCount; i++)
            {
                byte index = initialPacket.ReadByte();
                string name = initialPacket.ReadString();
                if (this._myName == name)
                {
                    this._myCamp = index == 0 ? Camp.Black : Camp.Red;
                }
            }

            //this._board = new ChessboardClient(this.panelChessBoard);

            foreach (Control lable in this.panelChessBoard.Controls)
            {
                if (lable is Label)
                {
                    lable.Click += new EventHandler(lable_Click);
                }
            }
        }

        [OneWay]
        public void ExchangeHand(int seatIndex)
        {
            this._currentSeatIndex = seatIndex;
        }

        [OneWay]
        public void ExchangeDesk(int deskId, int seatIndex)
        {
            this._mySeatIndex = seatIndex;
        }

        [OneWay]
        public void GameSynchronize(byte[] buffer)
        {
            Packet synchronizePacket = (Packet)PacketLoader.Default.Parse(buffer);
            int xOld = synchronizePacket.ReadInt32();
            int yOld = synchronizePacket.ReadInt32();
            int xNew = synchronizePacket.ReadInt32();
            int yNew = synchronizePacket.ReadInt32();

            this._board.MoveChessman(xOld, yOld, xNew, yNew);
        }

        [OneWay]
        public void GameOver(byte[] buffer)
        {
            Packet completedPacket = (Packet)PacketLoader.Default.Parse(buffer);
            int playerCount = completedPacket.ReadInt32();
            string msg = string.Empty;

            for (int i = 0; i < playerCount; i++)
            {
                msg += string.Format("{0}得分：{1}{2}", completedPacket.ReadString(), completedPacket.ReadInt32(), Environment.NewLine);
            }

            this.DoActionCrossThreads(() =>
            {
                MessageBox.Show(msg);
                this._board = new ChessboardClient(this.panelChessBoard);
            });
        }


        #endregion

        private void ChineseChessGameForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            RemoteServer.GetSingletomServer(Program.RemotePort).UnRegisterChild(this._key);
            RemoteServer.GetSingletomServer(Program.RemotePort).RequestChangeStatus(this._key, GameStatus.Absent);
        }

        private void ChineseChessGameForm_Load(object sender, EventArgs e)
        {
            RemoteServer.GetSingletomServer(Program.RemotePort).RegisterChild(this._key, this);
        }


    }
}
